/*
 * 代号：凤凰
 * http://www.jphenix.org
 * 2014-06-04
 * V4.0
 */
package com.jphenix.kernel.objectpool.instancea;

import com.jphenix.kernel.objectpool.interfaceclass.IObjectElement;
import com.jphenix.kernel.objectpool.interfaceclass.IObjectPool;
import com.jphenix.standard.docs.ClassInfo;

import java.util.concurrent.atomic.AtomicLong;

/**
 * 对象池元素类
 * 
 * 采用了父类继承方式实现池元素功能
 * 
 * 	必须实现类 terminat()  终止核心类实例
 * 
 * 2019-11-06 useTimeOut,freeTimeOut 小于0时，永不超时
 * 
 * @author 刘虻
 * 2006-8-12  17:45:59
 */
@ClassInfo({"2019-11-06 15:43","对象池元素类"})
public abstract class ObjectElement implements IObjectElement {

    protected IObjectPool pool = null; //对象池管理类
    
    protected long 
    		maxObjectCount = 100		//类实例最大并发数
    		,useTimeOut = 30000			//对象占用超时时间
    		,freeTimeOut = 60000;		//对象空闲超时时间

    
    private AtomicLong 
                        actionTime = new AtomicLong(0)             //比较占用时间
                        ,freeTime  = new AtomicLong(0);              //比较空闲时间
    protected String 
    		type = null					//元素类型
    		,pk = null;					//元素主键
    
    protected boolean 
    		ignoreException = false	//是否忽略异常（对象占用超时,是否强制关闭true或者抛出异常false）
    		,possess = false			//是否占用
    		,isAprivate = false;           //是否为私有元素
    
    /**
     * 构造函数 
     * @author 刘虻
     * 2006-8-12 17:45:59
     */
    public ObjectElement() {
        super();
    }
    
    /**
     * 结束元素
     * 刘虻
     * 2010-5-4 下午01:48:45
     */
    @Override
    public abstract void terminatElement();
    
    /**
     * 终止元素类 
     * @author  刘虻
     * 2006-8-13 13:49:01
     */
    @Override
    public void terminat() {
    		possess = false;
    		terminatElement();
    }
    
    /**
     * 覆盖方法
     * @author 刘虻
     * 2007-5-14下午01:16:03
     */
    @Override
    public void refreshAction() {
        actionTime.set(System.currentTimeMillis());
        possess = true;
    }


    /**
     * 覆盖方法
     * @author 刘虻
     * 2007-5-14下午01:16:24
     */
    @Override
    public long getFreeTimeOut() {
        return freeTimeOut;
    }
    
    /**
     * 覆盖方法
     * @author 刘虻
     * 2007-5-14下午01:16:35
     */
    public void setFreeTimeOut(long freeTimeOut) {
        this.freeTimeOut = freeTimeOut;
    }

    /**
     * 覆盖方法
     * @author 刘虻
     * 2007-5-14下午01:16:43
     */
    @Override
    public long getMaxObjectCount() {
        return maxObjectCount;
    }
    
    /**
     * 覆盖方法
     * @author 刘虻
     * 2007-5-14下午01:18:15
     */
    public void setMaxObjectCount(long maxObjectCount) {
        this.maxObjectCount = maxObjectCount;
    }

    /**
     * 覆盖方法
     * @author 刘虻
     * 2007-5-14下午01:18:18
     */
    @Override
    public long getUseTimeOut() {
        return useTimeOut;
    }

    /**
     * 覆盖方法
     * @author 刘虻
     * 2007-5-14下午01:18:25
     */
    public void setUseTimeOut(long useTimeOut) {
        this.useTimeOut = useTimeOut;
    }
    
    /**
     * 覆盖方法
     * @author 刘虻
     * 2007-5-14下午01:18:39
     */
    @Override
    public String getPK() {
        return pk;
    }

    /**
     * 覆盖方法
     * @author 刘虻
     * 2007-5-14下午01:18:44
     */
    @Override
    public void setPK(String pk) {
        this.pk = pk;
    }

    
    /**
     * 覆盖方法
     * @author 刘虻
     * 2007-5-14下午01:18:47
     */
    @Override
    public String getType() {
        return type;
    }

    /**
     * 覆盖方法
     * @author 刘虻
     * 2007-5-14下午01:18:55
     */
    @Override
    public void setType(String type) {
        this.type = type;
    }

    
    /**
     * 覆盖方法 
     * @author  刘虻
     * 2006-8-13 16:46:06
     */
    @Override
    public void freeElement() {
        freeTime.set(System.currentTimeMillis());
        possess = false;
        isAprivate = false;
        getPool().freeElement(this);
    }
    
    /**
     * 覆盖方法 
     * @author  刘虻
     * 2006-8-13 16:46:58
     */
    @Override
    public IObjectPool getPool() {
        return this.pool;
    }
    
    /**
     * 覆盖方法 
     * @author  刘虻
     * 2006-8-13 16:47:23
     */
    public void setPool(IObjectPool pool) {
        this.pool = pool;
    }
    
    
    /**
     * 覆盖方法
     * @author 刘虻
     * 2007-5-14下午01:19:18
     */
    @Override
    public boolean isPossess() {
        return possess;
    }

    /**
     * 覆盖方法
     * @author 刘虻
     * 2007-5-14下午01:19:23
     */
    public void setPossess(boolean possess) {
        this.possess = possess;
    }
    
    
    /**
     * 是否占用超时
     * 刘虻
     * 2010-5-4 上午11:14:38
     * @return true是
     */
    @Override
    public boolean isPossessTimeOut() {
    	if(!possess || useTimeOut<0) {
    		return false;
    	}
        return System.currentTimeMillis() > actionTime.get() + useTimeOut && useTimeOut > 0 && actionTime.get() > 0;
    }
    
    /**
     * 是否空闲超时
     * 刘虻
     * 2010-5-4 上午11:14:48
     * @return true是
     */
    @Override
    public boolean isNotUseTimeOut() {
    	if(possess || freeTimeOut<0) {
    		return false;
    	}
        return System.currentTimeMillis() > freeTime.get() + freeTimeOut && freeTimeOut > 0 && freeTime.get() > 0;
    }
    
    
    /**
     * 是否忽略异常（对象占用超时,是否强制关闭true或者抛出异常false）
     * 刘虻
     * 2010-5-4 下午12:49:17
     * @return true是
     */
    @Override
    public boolean isIgnoreException() {
    	return ignoreException;
    }
    
    
    /**
     * 设置是否忽略异常
     * 刘虻
     * 2010-5-4 下午12:53:21
     * @param ignoreException true是
     */
    public void setIgnoreException(boolean ignoreException) {
    	this.ignoreException = ignoreException;
    }
    
    /**
     * 是否为私有元素
     * @return 是否为私有元素
     * 2015年11月22日
     * @author 马宝刚
     */
    @Override
    public boolean isPrivate() {
        return isAprivate;
    }
    
    /**
     * 设置是否为私有元素
     * @param isPrivate 是否为私有元素
     * 2015年11月22日
     * @author 马宝刚
     */
    @Override
    public void isPrivate(boolean isPrivate) {
        this.isAprivate = isPrivate;
    }
}
